package com.junmeng.libfloating.base

import android.app.Activity
import android.app.Application
import android.util.SparseArray
import android.view.View
import com.junmeng.lib.ui.topview.core.IViewFactory
import com.junmeng.lib.ui.topview.core.WindowTopViewManager
import java.lang.RuntimeException

/**
 * 悬浮按钮管理
 */
open class FloatingManager {
    interface Listener {
        /**
         * 当用户自定义视图被添加时
         * @param type String IViewFactory.getType
         * @param child View 被添加的用户自定义视图
         * @param viewFactory IFloatingViewFactory
         */
        fun onAdd(type: String, child: View, viewFactory: IFloatingViewFactory) = Unit

        /**
         * 当用户自定义视图被移除时
         * @param type String IViewFactory.getType
         * @param child View 被移除的用户自定义视图
         * @param viewFactory IFloatingViewFactory?
         * @return Unit
         */
        fun onRemove(type: String, child: View, viewFactory: IFloatingViewFactory?) = Unit

        /**
         * 首个activity创建时
         * @param firstActivity Activity
         */
        fun onFirstActivityCreated(firstActivity: Activity)
    }

    private constructor()


    companion object {
        @JvmStatic
        open var application: Application? = null
        private var floatingManager: FloatingManager? = null

        @JvmStatic
        fun getInstance(): FloatingManager {
            return floatingManager ?: (FloatingManager().also { floatingManager = it })
        }
    }

    //    private var maps: SparseArray<IFloating> = SparseArray()
    // <悬浮球id,IFloating>
    private var maps: HashMap<String, IFloating> = hashMapOf()

    private var mListenerList: MutableList<Listener> = mutableListOf()

    fun addListener(listener: Listener) {
        mListenerList.add(listener)
    }

    fun removeListener(listener: Listener) {
        mListenerList.remove(listener)
    }


    /**
     * 初始化
     */
    open fun init(app: Application): FloatingManager {
        application = app
        WindowTopViewManager.init(app)
        WindowTopViewManager.addListener(object : WindowTopViewManager.Listener {
            override fun onAdd(type: String, child: View, viewFactory: IViewFactory) {
                if (viewFactory !is IFloatingViewFactory) {
                    return
                }
                mListenerList.forEach {
                    it.onAdd(type, child, viewFactory)
                }
            }

            override fun onRemove(type: String, child: View, viewFactory: IViewFactory?) {
                if (viewFactory !is IFloatingViewFactory) {
                    return
                }
                mListenerList.forEach {
                    it.onRemove(type, child, viewFactory)
                }
            }

            override fun onFirstActivityCreated(firstActivity: Activity) {
                mListenerList.forEach {
                    it.onFirstActivityCreated(firstActivity)
                }
            }
        })


        return this
    }

    /**
     * 反初始化，在不用时可以调用此及时释放资源
     */
    open fun uninit() {
        maps.clear()
        application = null
    }

    /**
     * 根据唯一标识获得FloatingBall
     *
     * @param id
     * @return
     */
    open fun getFloatingBall(id: String): IFloating? {
        checkInit()
        return maps[id]
    }

    /**
     * 获得FloatingBall
     * 刚好只存在一个时才返回，否则请调用[FloatingManager.getFloatingBall]
     *
     * @return
     */
    open fun getFloatingBall(): IFloating? {
        checkInit()
        return if (maps.size == 1) {
            maps.toList().first().second
        } else null
    }

    /**
     * 新建一个FloatingBall构建器
     *
     * @return
     */
    open fun newFloatingBallBuilder(): FloatingBall.Builder {
        checkInit()
        return FloatingBall.newBuilder()
    }

    /**
     * 检查是否调用初始化
     */
    private fun checkInit() {
        if (application == null) {
            throw RuntimeException("you must call init ")
        }
    }

    //以下暂不开放给外部使用
    /**
     * 注册
     *
     * @param id
     * @param floatingBall
     */
    internal fun register(id: String, floatingBall: FloatingBall) {
        maps.put(id, floatingBall)
    }

    /**
     * 反注册
     *
     * @param id
     */
    internal fun unregister(id: String) {
        maps.remove(id)
    }
}